package drds.plus.executor.function.scalar.subquery;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.ExecutorException;
import drds.plus.executor.cursor.cursor.ISortingCursor;
import drds.plus.executor.data_node_executor.DataNodeExecutorContext;
import drds.plus.executor.row_values.RowValues;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.abstract_syntax_tree.configuration.ColumnMetaData;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.FunctionName;
import drds.tools.$;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ScalarSubQuery extends AbstractSubQueryFunction {

    public String[] getFunctionNames() {
        return new String[]{FunctionName.subquery_scalar};
    }

    public Object compute(ExecuteContext executeContext, Object[] args) {
        Query query = this.getQuery(args);
        ISortingCursor cursor = null;
        try {
            Object result = null;
            cursor = DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().execute(executeContext, query);
            RowValues rowData = cursor.next();
            if (rowData != null) {
                ColumnMetaData columnMetaData = rowData.getParentCursorMetaData().getColumnMetaDataList().get(0);
                result = Utils.getValue(rowData, columnMetaData);
            } else {
                result = null;
            }

            if (cursor.next() != null) {
                throw new ExecutorException("sub setWhereAndSetNeedBuild return more than one row");
            }

            return result;
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        } finally {
            if (cursor != null) {
                List<RuntimeException> exs = new ArrayList();
                exs = cursor.close(exs);
                if ($.isNotNullAndHasElement(exs)) {
                    for (RuntimeException e : exs) {
                        log.warn("close subquery failed, exception is:", e);
                    }
                }
            }
        }

    }
}
